<template>
  <div class="loginBox">
    <h2>欢迎使用 味巷食铺</h2>
    <div>
      <van-divider>
        <div class="tabs">
          <span :class="[{ 'curTab': curTab === 1 }, 'tabIn', 'fs26', 'c-666']" @click="handleLoginType(1)">账号登录</span>
          <span :class="[{ 'curTab': curTab === 2 }, 'tabIn', 'fs26', 'c-666']"
            @click="handleLoginType(2)">手机快捷登录</span>
        </div>
      </van-divider>

      <van-form @submit="onSubmit" ref="formRef">
        <van-cell-group inset v-if="curTab === 1">
          <van-field v-model="formData.account" name="account" label="账号" placeholder="请输入账号/手机号码/邮箱" label-align="top"
            :rules="[{ required: true, message: '请填写账号/手机号码/邮箱' }, { validator: accountRules }]" />
          <van-field v-model="formData.password" :type="showPas ? 'text' : 'password'" name="password" label="密码"
            :rules="[{ required: true, message: '请填写密码' }, { validator: passwordRules }]" placeholder="请输入密码，8-20位字符"
            label-align="top">
            <template #right-icon>
              <van-icon :name="!showPas ? 'eye-o' : 'closed-eye'" @click="showPas = !showPas" />
            </template>
          </van-field>
        </van-cell-group>

        <div v-if="curTab === 1" class="mt20">
          <van-checkbox v-model="rememberPas" shape="square" icon-size="16" class="fs24">记住密码（15天内有效）</van-checkbox>
        </div>

        <van-cell-group inset v-if="curTab === 2">
          <van-field v-model="formData.phone" name="phone" label="手机号" placeholder="请输入手机号码" label-align="top"
            :rules="[{ required: true, message: '请填写手机号码' }, { validator: phoneRules }]" />
          <van-cell-group inset>
            <van-field v-model="formData.code" center clearable label="验证码" placeholder="请输入验证码" label-align="top"
              :rules="[{ required: true, message: '请填写验证码' }, { validator: codeRules }]">
              <template #button>
                <van-button size="small" type="primary" :disabled="codeInfo.isCodeSent" @click="sendCode">{{
                  codeInfo.timer ? `${codeInfo.codeTime}秒` : '短信验证' }}</van-button>
              </template>
            </van-field>
          </van-cell-group>
        </van-cell-group>

        <!-- <div id="captcha-el"></div> -->

        <div class="btnBox">
          <van-button round block type="primary" native-type="submit">
            登录
          </van-button>
        </div>

        <div class="flexBox flexcenterX mt30">
          <p class="fs28 c-666 f600 mr30">还没账号?</p>
          <RouterLink to="/register" class="fs28 c-main f600 mr30">立即注册</RouterLink>
          <RouterLink to="/forgotPass" class="fs28 c-main f600">忘记密码</RouterLink>
        </div>
        <!-- <div class="loginIconBox">
          <van-divider>其它登录方式</van-divider>
          <div class="flexBox flexcenterX">
            <van-image :src="qqImg" class="mr100 loginIcon" @click="handleThreeLogin('qq')" />
            <van-image :src="weImg" class="loginIcon" @click="handleThreeLogin('wx')" />
          </div>
        </div> -->
      </van-form>
    </div>
  </div>
</template>

<script setup lang="ts">
import { nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { RouterLink } from 'vue-router'
import { LoginForm } from '@/types/userTypes'
import { FieldRuleValidator, showToast } from 'vant'
import userStore from '@/store/modules/user'
import { loginApi, phoneLoginApi } from '@/api/user'
import router from '@/router'
import { clearLoginAccount, getLoginAccount, saveLoginAccount, setToken } from '@/utils/storage'
import qqImg from '@/assets/images/QQ.png'
import weImg from '@/assets/images/wechat.png'
import { debounce, isMobile, isWechat } from '@/utils'
import regConfig from '@/config/reg.config'
import { sendPhoneCode } from '@/api/common'
import config from '@/config'

// 验证码实例
let captchaInstance: any = null

const formRef = ref()
const showPas = ref(false)
const curTab = ref(1)
const isPhone = ref(false)
const rememberPas = ref(false)
const codeInfo = reactive({
  codeTime: 60,
  isCodeSent: false,
  timer: 0
})

const user = userStore()
const formData: LoginForm = reactive({
  account: '',
  password: '',
  phone: '',
  code: '',
  captchaParam: ''
})

const accountRules = (val: string) => {
  if (regConfig.email.test(val)) {
    return true
  }
  if (regConfig.phone.test(val)) {
    return true
  }

  if (!/^[a-zA-Z0-9_]+$/.test(val)) {
    return '账号只能包含字母、数字和下划线'
  }

  return true
}

const passwordRules: FieldRuleValidator = (val: string) => {
  if (val.length < 8 || val.length > 20) {
    return '密码长度为8-20位'
  }
  if (!/(?=.*[A-Za-z])(?=.*\d)/.test(val)) {
    return '密码必须包含字母和数字'
  }
  return true
}

const phoneRules: FieldRuleValidator = (val: string) => {
  if (!regConfig.phone.test(val)) {
    return '请输入正确的手机号'
  }
  return true
}

const codeRules: FieldRuleValidator = (val: number) => {
  if (!/^\d{6}$/.test(val.toString())) {
    return '请输入正确的验证码'
  }
  return true
}

const handleLoginType = (type: number) => {
  curTab.value = type
  isPhone.value = type === 2
}

const sendCode = debounce(async () => {
  if (codeInfo.isCodeSent) {
    return false
  }
  if (!formData.phone) {
    return showToast('请输入手机号')
  }
  codeInfo.isCodeSent = true

  try {
    const { data } = await sendPhoneCode({ phone: formData.phone })
    if (data.code === 0) {
      showToast('短信已发送')
      codeInfo.codeTime = 60
      codeInfo.timer = window.setInterval(() => {
        codeInfo.codeTime--
        if (codeInfo.codeTime < 1) {
          window.clearInterval(codeInfo.timer)
          codeInfo.timer = 0
          codeInfo.codeTime = 60
          codeInfo.isCodeSent = false
        }
      }, 1000)
    } else {
      showToast(data.msg || '短信发送失败')
      codeInfo.isCodeSent = false
    }
  } catch (err) {
    showToast(err || '短信发送失败')
    codeInfo.isCodeSent = false
  }
}, 1000, true)

const initCaptcha = () => {
  // 配置全局参数（必须在SDK加载前定义）
  window.AliyunCaptchaConfig = {
    region: config.captcha.region,
    prefix: config.captcha.prefix
  }

  // 动态加载验证码SDK
  const script = document.createElement('script')
  script.src = 'https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js'
  script.type = 'text/javascript'

  script.onload = () => {
    nextTick(() => {
      // 初始化验证码（弹出式）
      window.initAliyunCaptcha({
        SceneId: config.captcha.sceneId,
        mode: 'popup',
        element: '#captcha-el',
        // 验证成功回调
        success: async (param: string) => {
          formData.captchaParam = param
          // 验证码通过后执行登录请求
          showToast('验证码验证成功')
          await onSubmit(formData)
        },
        // 验证失败回调
        fail: (result: any) => {
          console.error('验证码失败:', result)
          showToast('验证码验证失败，请重试')
        },
        // 获取验证码实例
        getInstance: (instance: any) => {
          captchaInstance = instance
        },
        // 滑块样式
        slideStyle: {
          width: 360,
          height: 40
        }
      })
    })
  }

  script.onerror = () => {
    showToast('验证码SDK加载失败，请检查网络')
  }

  document.body.appendChild(script)
}

const handleLogin = async () => {
  const form = formRef.value
  if (!form) return

  try {
    await form.validate()
    // 表单验证通过，手动显示验证码弹窗
    if (captchaInstance) {
      captchaInstance.show()
    } else {
      showToast('验证码初始化中，请稍后重试')
    }
  } catch (error) {
    console.log('表单验证失败:', error)
    return
  }
}

const onSubmit = async (values: LoginForm) => {
  if (values) {
    const params = { ...values, code: formData.code }
    if (!isPhone.value) delete params.code

    const postFn = isPhone.value ? phoneLoginApi : loginApi
    const { data } = await postFn(params)
    if (data.code === 0) {
      showToast('登录成功，正在跳转')
      setToken(data.data.token)
      user.setUserInfo({ id: data.data.id })
      await user.getUserInfo()
      if (curTab.value === 1 && rememberPas.value) {
        saveLoginAccount(values.account, values.password)
      } else {
        clearLoginAccount()
      }
      setTimeout(() => {
        const redirectPath = localStorage.getItem('redirectAfterLogin') || '/'
        localStorage.removeItem('redirectAfterLogin')
        router.replace(redirectPath)
      }, 500)
    }
  }
}

const handleThreeLogin = async (type: string) => {
  if (type === 'qq') {
    // 生成防CSRF的随机state
    const state = 'qq_login_' + Math.random().toString(36).substr(2)
    const scope = 'get_user_info'
    const authUrl = `https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=${config.qq.appId}&redirect_uri=${encodeURIComponent(config.qq.callbackUrl)}&scope=${scope}&state=${state}`
    // window.location.href = authUrl
  } else {
    if (!isWechat()) {
      showToast('微信登录只支持在微信浏览器内使用!')
      return
    }
  }
}

onMounted(() => {
  // initCaptcha()
  if (curTab.value === 1) {
    const loginInfo = getLoginAccount()
    if (loginInfo) {
      formData.account = loginInfo.account
      formData.password = loginInfo.password
      rememberPas.value = true
    }
  }
})

onBeforeUnmount(() => {
  if (codeInfo.timer) clearInterval(codeInfo.timer)
})
</script>

<style lang="scss" scoped>
.loginBox {
  padding: 0 30px;
  padding-top: 320px;
  background: #F7F8FA;
  height: 100%;

  .tabs {
    .tabIn {
      padding: 0 10px;
      font-weight: bold;

      &:not(:last-child) {
        border-right: 1px solid #d8d8d8;
      }
    }
  }

  .loginIconBox {
    margin-top: 65px;

    .loginIcon {
      width: 72px;
    }
  }
}

h2 {
  font-size: 56px;
}

.btnBox {
  margin: 35px;
}

.van-divider {
  color: #6b7280;
}

.van-divider:before,
.van-divider:after {
  border-color: #d1d5db;
  border-top-width: 2px;
}

.van-cell-group--inset {
  margin: 0;
}

.van-cell {
  // padding-left: 0;
  // padding-right: 0;
}

.van-field__control {
  border: 5px solid #d9d9d9 !important;
}

.curTab {
  color: #ec6300;
}
</style>